package com.luo.sc.oidc.authserver.handler.kapatcha;

import com.google.code.kaptcha.text.impl.DefaultTextCreator;

import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.function.BiFunction;

/**
 * 算术表达式（2个数字加减乘除）验证码文本生成器，生成如下形式验证码：
 * <ul>
 *     <li>1*2=?</li>
 *     <li>4/2=?</li>
 *     <li>3+4=?</li>
 *     <li>7-5=?</li>
 * </ul>
 * 返回结果格式：表达式@结果，如 2+4=?@6
 *
 * @author luohq
 * @version 1.0.0.
 * @date 2022-03-04
 */
public class KaptchaMathExpTextCreator extends DefaultTextCreator {

    public static final String MATH_SEPARATOR = "@";
    public static final String EQUAL_QUESTION_SEPARATOR = "=?@";

    private Map<Integer, BiFunction<Integer, Integer, String>> operand2FuncMap = new HashMap<>(4);


    public KaptchaMathExpTextCreator() {
        super();
        this.operand2FuncMap.put(0, this::typePlus);
        this.operand2FuncMap.put(1, this::typeMinus);
        this.operand2FuncMap.put(2, this::typeMul);
        this.operand2FuncMap.put(3, this::typeDivide);
    }

    /**
     * 返回算法表达式验证码<br/>
     * 格式：表达式@结果，如 2+4=?@6
     *
     * @return
     */
    @Override
    public String getText() {
        Random random = new Random();
        //10以内随机数x，y
        int x = random.nextInt(10);
        int y = random.nextInt(10);
        //文本生成类型{0,1,2,3}
        int randomOperands = random.nextInt(4);
        return this.operand2FuncMap.get(randomOperands).apply(x, y);
    }

    private String typePlus(Integer x, Integer y) {
        Integer result = x + y;
        return new StringBuilder(String.valueOf(x))
                .append("+")
                .append(y)
                .append(EQUAL_QUESTION_SEPARATOR)
                .append(result)
                .toString();
    }

    private String typeMinus(Integer x, Integer y) {
        Integer max = Math.max(x, y);
        Integer min = Math.min(x, y);
        Integer result = max - min;
        return new StringBuilder(String.valueOf(max))
                .append("-")
                .append(min)
                .append(EQUAL_QUESTION_SEPARATOR)
                .append(result)
                .toString();
    }

    private String typeMul(Integer x, Integer y) {
        Integer result = x * y;
        return new StringBuilder(String.valueOf(x))
                .append("*")
                .append(y)
                .append(EQUAL_QUESTION_SEPARATOR)
                .append(result)
                .toString();
    }

    private String typeDivide(Integer x, Integer y) {
        //整除
        if (x != 0 && y % x == 0) {
            Integer result = y / x;
            return new StringBuilder(String.valueOf(y))
                    .append("/")
                    .append(x)
                    .append(EQUAL_QUESTION_SEPARATOR)
                    .append(result)
                    .toString();
        }
        //否则退化为相加
        return this.typePlus(x, y);
    }

}
